//
//  ViewController.swift
//  TestDemo
//
//  Created by ayin on 2019/2/11.
//  Copyright © 2019 aYin. All rights reserved.
//

import UIKit
import MobileCoreServices
import AssetsLibrary
import Photos

import AVKit
import AVFoundation
import PLPlayerKit
import PLShortVideoKit

let screenWidth: CGFloat = UIScreen.main.bounds.size.width

let screenHeight: CGFloat = UIScreen.main.bounds.size.height

let statusBarAndNavigationBarHeight: CGFloat = iPhoneX ? 88.0 : 64.0

var iPhoneX: Bool {
    if screenHeight == 812 || screenHeight == 896{
        return true
    }else{
        return false
    }
}

enum FileUpdateState {
    case wait
    case loading
    case finish
}

class videoModel: NSObject {
    var fileType:String = ""
    var filePath:String = ""
    var fileName:String = ""
    var fileSize:NSInteger = 0
    var trunks:NSInteger = 0
    var fileImage:UIImage = UIImage()
    var fileUPState:FileUpdateState = .wait
}

class ViewController: UIViewController,UIImagePickerControllerDelegate,
UINavigationControllerDelegate {
    
    let imagePicker = UIImagePickerController()
    let imageView = UIImageView(frame: CGRect(x: 200, y: 150, width: 100, height: 100))
    
    let navRightBtn = UIButton.makeButton(font: UIFont.systemFont(ofSize: 14), title: "确定 ", titleColor: UIColor.red, image: nil, bgColor: UIColor.clear)

    var count:Int = 0
    var videoList:[TZAssetModel] = []
    var path:String = ""
    var compressPath:String = ""
    var progressView:VideoPublishProgressView = VideoPublishProgressView()

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.white
        
        navigationItem.rightBarButtonItem = UIBarButtonItem(customView: navRightBtn)
        
        
        //创建一个ContactAdd类型的按钮
        let button:UIButton = UIButton(type:.system)
        button.frame = CGRect(x:10, y:150, width:100, height:30)
        button.setTitle("选择视频", for:.normal)
        button.addTarget(self, action:#selector(selectVideo), for:.touchUpInside)
        self.view.addSubview(button)
        
        //创建一个ContactAdd类型的按钮
        let button2:UIButton = UIButton(type:.system)
        button2.frame = CGRect(x:10, y:200, width:100, height:30)
        button2.setTitle("播放原视频", for:.normal)
        button2.addTarget(self, action:#selector(playVideo1), for:.touchUpInside)
        self.view.addSubview(button2)
        
        //创建一个ContactAdd类型的按钮
        let button3:UIButton = UIButton(type:.system)
        button3.frame = CGRect(x:10, y:250, width:100, height:30)
        button3.setTitle("播放压缩视频", for:.normal)
        button3.addTarget(self, action:#selector(playVideo2), for:.touchUpInside)
        self.view.addSubview(button3)
        
        self.view.addSubview(imageView)
        
        imagePicker.delegate = self
        imagePicker.mediaTypes = [kUTTypeMovie as String]
        
        progressView.isHidden = true
        self.view.addSubview(progressView)
        
        progressView.snp.makeConstraints { (make) in
            make.top.equalTo(350)
            make.left.width.equalToSuperview()
            make.height.equalTo(53)
        }
        
        self.getAllVideoList()
    }
    
    deinit {
        //需要removeObserverBlocks
    }
    
    //MARK: - 事件
    func getAllVideoList() {
        DispatchQueue.global().async {
            TZImagePickerConfig.sharedInstance()?.allowPickingVideo = true
            TZImagePickerConfig.sharedInstance().gifPreviewMaxImagesCount = 10
            TZImageManager.default()?.getAllAlbums(true,
                                                   allowPickingImage: false,
                                                   needFetchAssets: true,
                                                   completion: { (albums) in
                                                    if let all = albums, all.count > 0 {
                                                        // 将三方模型转换成自己的模型，更新相册数组
                                                        for model in all {
                                                            if model.name == "Videos" {
                                                                self.videoList = model.models as! [TZAssetModel]
                                                                return
                                                            }
                                                        }
                                                    }
            })
        }
    }
    
    @objc func selectVideo() {
        if count < self.videoList.count {
            let videoModel:TZAssetModel = self.videoList[count]
            let videoAsset:PHAsset = videoModel.asset!
            
            let manager = PHImageManager.default()
            
            let videoOption = PHVideoRequestOptions()
            videoOption.version = .current
            videoOption.deliveryMode = .automatic
            manager.requestAVAsset(forVideo: videoAsset, options: videoOption, resultHandler: { (asset, audioMix, info) in
                guard let videoUrlAsset:AVURLAsset = asset as? AVURLAsset else {return}
                let url = videoUrlAsset.url
                self.path = url.relativePath
                
                print("原始视频:")
                self.printVideoInfo(self.path)
                
//                self.publicAction(url)
                

//                self.compressVideoWithSourcePath(self.path, { (compressPath) in
//                    self.compressPath = compressPath
//                })
                
                self.compress3VideoWithSourcePath(self.path, { (compressPath) in
                    self.compressPath = compressPath
                })
                
//                self.qiniuCompressVideoWithSourcePath(self.path, { (compressPath) in
//                    self.compressPath = compressPath
//                })
            })
            
            let imageOption = PHImageRequestOptions() //可以设置图像的质量、版本、也会有参数控制图像的裁剪
            imageOption.isSynchronous = true
            manager.requestImage(for: videoAsset, targetSize: CGSize.init(width: 200, height: 200), contentMode: .aspectFill, options: imageOption) { (thumbnailImage, info) in
                self.imageView.image = thumbnailImage
            }
            count = count + 1
        }
        
//        if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
//            imagePicker.sourceType = .photoLibrary
//            imagePicker.allowsEditing = false
//            self.present(imagePicker, animated: true, completion: nil)
//        }else {
//            print("读取相册错误")
//        }
    }
    
    @objc func playVideo1() {
        if path.count > 0 {
            let player = AVPlayer(url: URL(fileURLWithPath: path))
            let playerViewController = AVPlayerViewController()
            playerViewController.player = player
            self.present(playerViewController, animated: true) {
                playerViewController.player!.play()
            }
        }
    }
    
    @objc func playVideo2() {
        if compressPath.count > 0 {
            
//            let ll = TestPlayVideoVC()
//            ll.videoUrl = URL(fileURLWithPath: compressPath)
//            self.present(ll, animated: true, completion: nil)
            
            let player = AVPlayer(url: URL(fileURLWithPath: compressPath))
            let playerViewController = AVPlayerViewController()
            playerViewController.player = player
            self.present(playerViewController, animated: true) {
                playerViewController.player!.play()
            }
        }
    }
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        //获取视频路径（选择后视频会自动复制到app临时文件夹下）
        let mediaType = info[UIImagePickerController.InfoKey.mediaType] as! String
        if mediaType == "public.movie" {
            let videoURL = info[UIImagePickerController.InfoKey.mediaURL] as! URL
            let pathString = videoURL.relativePath
            print("视频地址：\(pathString)")

            if #available(iOS 11.0, *) {
                let videoAsset = info[UIImagePickerController.InfoKey.phAsset] as! PHAsset
                print("duration:\(videoAsset.duration)")

                let manager = PHImageManager.default()
                let option = PHImageRequestOptions() //可以设置图像的质量、版本、也会有参数控制图像的裁剪
                option.isSynchronous = true
                
                manager.requestImage(for: videoAsset, targetSize: CGSize.init(width: 200, height: 200), contentMode: .aspectFit, options: option) { (thumbnailImage, info) in
                    self.imageView.image = thumbnailImage
                }
                
                manager.requestImage(for: videoAsset, targetSize:PHImageManagerMaximumSize, contentMode: .aspectFit, options: option) { (originImage, info) in
                    self.imageView.image = originImage
                }
                self.compressVideoWithSourcePath(pathString) { (compressPath) in
                    print(compressPath)
                }
            } else {
                let alUrl = info[UIImagePickerController.InfoKey.referenceURL] as! URL
                let videoAssets = PHAsset.fetchAssets(withALAssetURLs: [alUrl], options: nil)
                let vAsset = videoAssets.firstObject!
                print("duration:\(vAsset.duration)")
            }

            let videoURLAsset = AVURLAsset(url: videoURL, options: nil)
            let videoTime = CMTimeGetSeconds(videoURLAsset.duration)
            print("duration:\(videoTime)")
        }
        
        //图片控制器退出
        self.dismiss(animated: true, completion: {})
    }

    // 获取当前时间戳
    func currentTimeStamp()->String {
        let now = Date()
        let dformatter = DateFormatter()
        dformatter.dateFormat = "yyyy年MM月dd日 HH:mm:ss"
        //当前时间的时间戳
        let timeInterval:TimeInterval = now.timeIntervalSince1970
        let timeStamp = Int(timeInterval)
        return String(timeStamp)
    }
    
    // 删除本地文件
    func deleteFile(path:String) {
        if FileManager.default.fileExists(atPath: path) {
            try? FileManager.default.removeItem(atPath: path)
        }
    }
    
//    //获取视频封面截图
//    class func getVideoCropPicture(videoUrl: URL) -> UIImage {
//        let avAsset = AVAsset(url: videoUrl)
//        let generator = AVAssetImageGenerator(asset: avAsset)
//        generator.appliesPreferredTrackTransform = true
//        let time = CMTimeMakeWithSeconds(0.0, 600)
//        var actualTime: CMTime = CMTimeMake(0, 0)
//        let imageP = try? generator.copyCGImage(at: time, actualTime: &actualTime)
//        let image = UIImage.init(cgImage: imageP!)
//        return image
//    }
}

extension ViewController {
    //MARK: - 压缩方法
    //方法1：
    func compressVideoWithSourcePath(_ filePath:String,_ completion:@escaping (((_ compressFilePath:String) -> Void))) {
        let videoURL = URL.init(fileURLWithPath: filePath)
        let avURLAsset = AVURLAsset.init(url: videoURL)
        guard let assetExport = AVAssetExportSession(asset: avURLAsset, presetName: AVAssetExportPresetMediumQuality) else {
            return
        }
        
        //设置导出路径
        let name = currentTimeStamp() + ".mp4"
        let temporaryFilePath = NSTemporaryDirectory() + name
        let outputFileUrl = URL(fileURLWithPath: temporaryFilePath)
        
        assetExport.outputFileType = .mp4// 输出类型
        assetExport.outputURL = outputFileUrl// 输出地址
        assetExport.shouldOptimizeForNetworkUse = true// 优化
        
        if FileManager.default.fileExists(atPath: temporaryFilePath) {
            completion(temporaryFilePath)
            return
        }
        
        assetExport.exportAsynchronously(completionHandler: {
            switch assetExport.status {
            case .unknown:
                print("----------------unknown")
            case .waiting:
                print("----------------waiting")
            case .exporting:
                print("----------------exporting")
            case .completed:
                print("----------------completed")
                //转码成功
                completion(temporaryFilePath)
            case .failed:
                print("----------------failed")
            case .cancelled:
                print("----------------cancelled")
            }
        })
        
        print("progress----------------\(assetExport.progress)")
    }
    
    func qiniuCompressVideoWithSourcePath(_ filePath:String,_ completion:@escaping (((_ compressFilePath:String) -> Void))) {
        let transcoder:PLShortVideoTranscoder = PLShortVideoTranscoder(url: URL(fileURLWithPath: self.path))
//        transcoder.outputFileType = .MPEG4
//        transcoder.outputFilePreset = .preset960x540
        transcoder.bitrate = 3000 * 1000// 设置码率
        transcoder.completionBlock = { url in
            print("七牛压缩完成视频地址--------------\(url?.relativePath ?? "")")
            self.compressPath = (url?.relativePath)!
            completion((url?.relativePath)!)
        }
        transcoder.failureBlock = { error in

        }
        transcoder.processingBlock = { process in
            print("七牛压缩进度--------------\(process)")
        }
        transcoder.startTranscoding()
    }
    
    //方法2：
    func compress2VideoWithSourcePath(_ filePath:String,_ completion:@escaping (((_ compressFilePath:String) -> Void))) {
        let videoURL = URL.init(fileURLWithPath: filePath)
        //设置导出路径
        let name = currentTimeStamp() + ".mp4"
        let temporaryFilePath = NSTemporaryDirectory() + name
        let outputFileUrl = URL(fileURLWithPath: temporaryFilePath)
        
        let avAsset = AVAsset(url: videoURL)
        let reader = try? AVAssetReader(asset: avAsset)
        let writer = try? AVAssetWriter(outputURL: outputFileUrl, fileType: .mp4)
        
        //video部分
        let videoTrack = avAsset.tracks(withMediaType: .video).first!
        let videoOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings: self.videoCompressSettings())
        let videoInput = AVAssetWriterInput(mediaType: .video, outputSettings: self.videoCompressSettings())
        if (reader?.canAdd(videoOutput))! {
            reader?.add(videoOutput)
        }
        
        if (writer?.canAdd(videoInput))! {
            writer?.add(videoInput)
        }
        
        //audio部分
        let audioTrack = avAsset.tracks(withMediaType: .audio).first!
        let audioOutput = AVAssetReaderTrackOutput(track: audioTrack, outputSettings: self.audioCompressSettings())
        let audioInput = AVAssetWriterInput(mediaType: .audio, outputSettings: self.audioCompressSettings())
        if (reader?.canAdd(audioOutput))! {
            reader?.add(audioOutput)
        }
        
        if (writer?.canAdd(audioInput))! {
            writer?.add(audioInput)
        }
        
        //开始读写
        reader?.startReading()
        writer?.startWriting()
        writer?.startSession(atSourceTime: .zero)
        
        //视频逐帧写入
        let group = DispatchGroup()
        group.enter()
        videoInput.requestMediaDataWhenReady(on: DispatchQueue.global()) {
            while videoInput.isReadyForMoreMediaData {
                if reader?.status == .reading, let sampleBuffer = videoOutput.copyNextSampleBuffer() {
                    let result:Bool = videoInput.append(sampleBuffer)
                    if !result {
                        reader?.cancelReading()
                        break
                    }
                }else {
                    videoInput.markAsFinished()
                    group.leave()
                }
            }
        }
        
        //音频逐帧写入
        group.enter()
        audioInput.requestMediaDataWhenReady(on: DispatchQueue.global()) {
            while audioInput.isReadyForMoreMediaData {
                if reader?.status == .reading,let sampleBuffer = audioOutput.copyNextSampleBuffer() {
                    let result:Bool = audioInput.append(sampleBuffer)
                    if !result {
                        reader?.cancelReading()
                        break
                    }else {
                        videoInput.markAsFinished()
                        group.leave()
                    }
                }
            }
        }
        
        //完成压缩
        group.notify(queue: DispatchQueue.global()) {
            if reader?.status == .reading {
                reader?.cancelReading()
            }
            switch writer?.status {
            case .writing? :
                writer?.finishWriting(completionHandler: {
                    completion(temporaryFilePath)
                })
            default:
                break
            }
        }
    }
    
    //方法3：
    func compress3VideoWithSourcePath(_ filePath:String,_ completion:@escaping (((_ compressFilePath:String) -> Void))) {
        let videoURL = URL.init(fileURLWithPath: filePath)
        
        //设置导出路径
        let name = currentTimeStamp() + ".mp4"
        let temporaryFilePath = NSTemporaryDirectory() + name
        let outputFileUrl = URL(fileURLWithPath: temporaryFilePath)
        
        let avAsset = AVAsset(url: videoURL)
        let encoder = SDAVAssetExportSession(asset: avAsset)
        encoder?.outputFileType = AVFileType.mp4.rawValue
        encoder?.outputURL = outputFileUrl
        encoder?.videoSettings = self.videoCompressSettings()
        encoder?.videoSettings2 = self.videoCompressSettings2()
        encoder?.audioSettings = self.audioCompressSettings()
        encoder?.exportAsynchronously(progress: { (progress) in
            
        }, completionHandler: {
            if encoder?.status == .completed {
                completion(temporaryFilePath)
                print("压缩视频:")
                self.printVideoInfo(temporaryFilePath)
            }else if encoder?.status == .cancelled {
                
            }else {
            }
        })
        
//        encoder?.addObserver(self, forKeyPath: "progress", options: [.new, .old], context: nil)
        
    }
    
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if let keyPath = keyPath,
            keyPath.count > 0,
            keyPath == "progress",
            let change = change{
            print("---------\(change[.newKey])")
        }
    }
    
    
    //指定音视频的压缩码率，profile，帧率等关键参数信息
    func videoCompressSettings() -> [String : Any] {
        let compressionProperties: [String : Any] = [AVVideoAverageBitRateKey : 1024*1024*2,
                                                   AVVideoProfileLevelKey : AVVideoProfileLevelH264HighAutoLevel]
        let videoCompreesSetings: [String : Any] = [AVVideoCodecKey : AVVideoCodecH264,
                                                    AVVideoWidthKey : 1080,
                                                    AVVideoHeightKey : 1920,
                                                    AVVideoCompressionPropertiesKey :compressionProperties]
        return videoCompreesSetings
    }
    
    func videoCompressSettings2() -> [String : Any] {
        let compressionProperties: [String : Any] = [AVVideoAverageBitRateKey : 1024*1024*2,
                                                     AVVideoProfileLevelKey : AVVideoProfileLevelH264HighAutoLevel]
        let videoCompreesSetings: [String : Any] = [AVVideoCodecKey : AVVideoCodecH264,
                                                    AVVideoWidthKey : 1080,
                                                    AVVideoHeightKey : 1920,
                                                    AVVideoCompressionPropertiesKey :compressionProperties]
        return videoCompreesSetings
    }
    
    func audioCompressSettings() -> [String: Any] {
//        var stereoChannelLayout = AudioChannelLayout()
//        stereoChannelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo
//        stereoChannelLayout.mChannelBitmap = .bit_Left
//        stereoChannelLayout.mNumberChannelDescriptions = 0
//        let channelLayoutAsData = Data.init(bytes: &stereoChannelLayout, count: 100)
        let audioCompressSettings: [String : Any] = [AVFormatIDKey : kAudioFormatMPEG4AAC,
                                                     AVEncoderBitRateKey : 128000,
                                                     AVSampleRateKey : 44100,
                                                     AVNumberOfChannelsKey : 2]
//        AVChannelLayoutKey : channelLayoutAsData
        return audioCompressSettings
    }
    
    //MARK: - 其他
    //打印
    func printVideoInfo(_ filePath:String) {
        let now = Date()
        let dformatter = DateFormatter()
        dformatter.dateFormat = "yyyy年MM月dd日 HH:mm:ss"
        
        print("path:\(filePath)")
        filePath.getFileSize { (size,error)  in
            let recordSize = size!/1024/1024
            print("当前时间：\(dformatter.string(from: now as Date))，视频大小：\(recordSize)")
        }
    }
}

extension ViewController {
    //MARK: - 数据请求
    func videoUpdateRequest(filePath:String) {
        QNContentUploadManager.share.uploadVideo(filePath: filePath, token: "e5V7IxNlpwSgfK7xQJKi3PAV3c2vzQu0BqVhMtKW:KKfD3HqGXlG9-279glgyxDRdCzU=:eyJzY29wZSI6InVwdGVzdCIsImRlYWRsaW5lIjoxNDg0OTE4ODA1fQ==", progressBlock: nil, responseBlock: { (isSuccess, isTokenError, text) in
            print("----------------\(text ?? "")")
            self.deleteFile(path: filePath)
        })
    }
}

extension ViewController {
    func publicAction(_ videoUrl:URL) {
        DispatchQueue.main.async {
            self.progressView.isHidden = false
            self.progressView.startUploadVideo(videoUrl) { [weak self] (state, model) in
                guard let weakSelf = self else {return}
                switch state {
                case .success:
                    print("--------uploadVideoSuccess")
                    weakSelf.progressView.isHidden = true
                case .close:
                    print("--------uploadVideoClose")
                    weakSelf.progressView.refreshUIWithSlide()
                case .error:
                    print("--------uploadVideoError")
                }
            }
        }
    }
}




///            let image = info[UIImagePickerControllerOriginalImage] as! UIImage
//            // 设置筛选条件
//            let allPhotosOptions = PHFetchOptions()
//            // 按图片生成时间排序
//            allPhotosOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
//            //选择普通照片
//            allPhotosOptions.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.image.rawValue)
//            //本地路径，代替ReferenceURL
//            var localIdentifier: String = ""
//            //通过存储图片到本地路径，顺便拿到Url
//            PHPhotoLibrary.shared().performChanges({
//                //
//                let createdAssetID = PHAssetChangeRequest.creationRequestForAsset(from: image).placeholderForCreatedAsset?.localIdentifier
//                localIdentifier = createdAssetID!
//                print("createdAssetID:\(createdAssetID ?? "nil")")
//            }) { (success, error) in
//                //通过localIdentifier 拿到PHAsset对象
//                let assets = PHAsset.fetchAssets(withLocalIdentifiers: [localIdentifier], options: allPhotosOptions)
//                if assets.firstObject != nil
//                {
//                    //这里拿到了PHAsset对象，往下操作就看自己的需求了
//                    self.dataSource.insert(assets.firstObject!, at: self.dataSource.count - 1)
//
//                    DispatchQueue.main.async {
//                        self.collectionView.reloadData()
//                    }
//                }
//            }





//        if UIImagePickerController.isSourceTypeAvailable(.camera) {
//            imagePicker.sourceType = .camera
//            imagePicker.allowsEditing = true
//            imagePicker.videoMaximumDuration = 6
//            imagePicker.videoQuality = .typeMedium
//
//            let view = UIView(frame: CGRect(x: 0, y: 100, width: 100, height: 100))
//            view.backgroundColor = UIColor.red
//            imagePicker.cameraOverlayView = view
//
//
//
//            self.present(imagePicker, animated: true, completion: nil)
//        }else {
//            print("相机不可用")
//        }

